<template>
  <Popover
    placement="bottom"
    trigger="click"
    v-model="visible"
    :overlayClassName="`${prefixCls}-popover`"
  >

    <template #content>
      <div v-if="getPaginationList.length" >
        <ScrollContainer class="border border-solid border-gray-400  pt-2" >
          <ul class="flex flex-wrap px-2">
            <li
              v-for="icon in getPaginationList"
              :key="icon"
              :class="currentSelect === icon ? 'border border-primary' : ''"
              class="p-2 w-1/8 cursor-pointer mr-1 mt-1 flex justify-center items-center border border-solid hover:border-primary"
              @click="handleClick(icon)"
              :title="icon"
            >
              <SvgIcon v-if="isSvgMode" :name="icon" />
              <Icon :icon="icon" v-else />
            </li>
          </ul>
        </ScrollContainer>
        <div class="flex py-2 items-center justify-center" v-if="getTotal >= pageSize">
          <Pagination
            showLessItems
            size="small"
            :pageSize="pageSize"
            :total="getTotal"
            @change="handlePageChange"
          />
        </div>
      </div>
      <template v-else>
        <div class="p-5"><Empty /> </div>
      </template>
    </template>
  <Input
    :style="{ width }"
    :placeholder="t('component.icon.placeholder')"
    :class="prefixCls"
    v-model:value="currentSelect"
    @click="triggerPopover"
    :allowClear="props.allowClear"
    :readonly="props.readonly"
    @change="debounceHandleSearchChange"
  >
    <template #addonBefore v-if="isIconAlignLeft">
        <!-- 图标按钮 -->
        <div ref="trigger">
          <span
            class="cursor-pointer px-2 py-1 flex items-center"
            v-if="isSvgMode && currentSelect"
          >
            <SvgIcon :name="currentSelect" />
          </span>
          <Icon
            :icon="currentSelect || 'ion:apps-outline'"
            class="cursor-pointer px-2 py-1"
            v-else
          />
        </div>
    </template>
    <template #addonAfter v-else>
      <!-- 图标按钮 -->
      <div ref="trigger">
          <span
            class="cursor-pointer px-2 py-1 flex items-center"
            v-if="isSvgMode && currentSelect"
          >
            <SvgIcon :name="currentSelect" />
          </span>
        <Icon
          :icon="currentSelect || 'ion:apps-outline'"
          class="cursor-pointer px-2 py-1"
          v-else
        />
      </div>
    </template>
  </Input>
  </Popover>

</template>
<script lang="ts" setup>
  import { ref, watchEffect, watch } from 'vue';
  import { useDesign } from '@/hooks/web/useDesign';
  import { ScrollContainer } from '@/components/Container';
  import { Input, Popover, Pagination, Empty } from 'ant-design-vue';
  import Icon from '../Icon.vue';
  import SvgIcon from './SvgIcon.vue';

  import iconsData from '../data/icons.data';
  import { usePagination } from '@/hooks/web/usePagination';
  import { useDebounceFn } from '@vueuse/core';
  import { useI18n } from '@/hooks/web/useI18n';
  import svgIcons from 'virtual:svg-icons-names';
  import { copyText } from '@/utils/copyTextToClipboard';

  import { search } from '@/api/icon/iconify';

  function getIcons() {
    const prefix = iconsData.prefix;
    return iconsData.icons.map((icon) => `${prefix}:${icon}`);
  }

  function getSvgIcons() {
    return svgIcons.map((icon: string) => icon.replace('icon-', ''));
  }

  // 支持的配置参数
  export interface Props {
    value?: string;
    width?: string;
    pageSize?: number;
    copy?: boolean;
    mode?: 'svg' | 'iconify' | 'local'
    allowClear?: boolean;
    readonly?: boolean;
    iconAlign?: 'left' | 'right';
  }
  const props = withDefaults(defineProps<Props>(), {
    value: '',
    width: '100%',
    pageSize: 140,
    copy: false,
    mode: 'local',
    allowClear: true,
    readonly: false,
  });

  // Don't inherit FormItem disabled、placeholder...
  defineOptions({
    inheritAttrs: false,
  });

  // 触发父组件事件
  const emit = defineEmits(['change', 'update:value']);

  const isSvgMode = props.mode === 'svg';
  const isIconAlignLeft =  props.iconAlign === 'left';
  const icons = isSvgMode ? getSvgIcons() : getIcons();

  const currentSelect = ref('');
  const visible = ref(false);
  const currentList = ref(icons);
  const trigger = ref<HTMLDivElement>();

  const triggerPopover = () => {
    if (trigger.value) {
      trigger.value.click();
    }
  };

  const { t } = useI18n();
  const { prefixCls } = useDesign('icon-picker');

  const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 500);

  const { getPaginationList, getTotal, setCurrentPage } = usePagination(
    currentList,
    props.pageSize,
  );

  watchEffect(() => {
    currentSelect.value = props.value;
  });

  watch(
    () => currentSelect.value,
    (v) => {
      emit('update:value', v);
      emit('change', v);
    },
  );
  function handlePageChange(page: number) {
    setCurrentPage(page);
  }

  function handleClick(icon: string) {
    currentSelect.value = icon;
    if (props.copy) {
      copyText(icon, t('component.icon.copy'));
    }
  }

  async function  handleSearchChange(e: Event) {
    const value = (e.target as HTMLInputElement).value;

    if (!value) {
      setCurrentPage(1);
      currentList.value = icons;
      return;
    }
    if(props.mode == 'local'){
      currentList.value = icons.filter((item) => item.includes(value));
    }else {
      let respData = await search(value);
      currentList.value = respData.icons;
    }
  }
</script>
<style lang="less">
  @prefix-cls: ~'@{namespace}-icon-picker';

  .@{prefix-cls} {
    .ant-input-group-addon {
      padding: 0;
    }

    .ant-input {
      cursor: pointer;
    }

    &-popover {
      width: 300px;

      .ant-popover-inner-content {
        padding: 0;
      }

      .scrollbar {
        height: 220px;
      }
    }
  }
</style>
